#include "FileHandler.h"


FileHandler::FileHandler() {

}

ArchivoAuxiliar* FileHandler::merge(ArchivoAuxiliar* file, vector<RegistroAuxiliar>& buffer) {

    stringstream filename(stringstream::in | stringstream::out);
    filename << "IndiceInvertidoAux";

    //La primera vez copio todo en un archivo.
    if (file == NULL) {
        file = new ArchivoAuxiliar(filename.str().c_str());
        for (unsigned int i = 0; i < buffer.size(); i++) {
            RegistroAuxiliar reg = buffer.at(i);
            file->write(reg);
        }
        file->flush();
        file->rename("IndiceInvertido");

        return file;
    }

    ArchivoAuxiliar *resFile = new ArchivoAuxiliar(filename.str().c_str());
    file->clear();
    file->seekg(0, ios::beg);

    vector<RegistroAuxiliar>::iterator it = buffer.begin();
    RegistroAuxiliar *rFile = new RegistroAuxiliar();
    int result = file->read(rFile);

    while (it != buffer.end()) {

        RegistroAuxiliar buffer = *it;

        if (!rFile || buffer.getTermino() < rFile->getTermino()) {
            resFile->write(buffer);
            it++;
        }else if (rFile->getTermino() < buffer.getTermino()) {
            resFile->write(*rFile);
            delete (rFile);

            if (result == RES_EOF)
                rFile = NULL;
            else {
                rFile = new RegistroAuxiliar();
                result = file->read(rFile);
            }

        } else {
            //Mismo termino, actualizo y copio.
            RegistroAuxiliar* rMerge = new RegistroAuxiliar();
            rMerge->setTermino(rFile->getTermino());
            vector<uint32_t>* nroDocs = rFile->getDocumentos();

            for (unsigned int i = 0; i < nroDocs->size(); i++) {
                rMerge->agregarDocumento(nroDocs->at(i));

                vector<uint32_t> p = rFile->getPosiciones(nroDocs->at(i));

                for (unsigned int j = 0; j < p.size(); j++)
                    rMerge->agregarPosicion(nroDocs->at(i), p.at(j));
            }

            vector<uint32_t>* docs = buffer.getDocumentos();

            for (unsigned int i = 0; i < docs->size(); i++) {
                rMerge->agregarDocumento(docs->at(i));
                vector<uint32_t> p = buffer.getPosiciones(docs->at(i));

                for (unsigned int j = 0; j < p.size(); j++)
                    rMerge->agregarPosicion(docs->at(i), p.at(j));

            }

            nroDocs->clear();
            docs->clear();

            it++;
            delete (rFile);

            if (result == RES_EOF)
                rFile = NULL;
            else {
                rFile = new RegistroAuxiliar();
                result = file->read(rFile);
            }

            resFile->write(*rMerge);
            delete (rMerge);
        }

    }

    if (rFile) {
        resFile->write(*rFile);
        delete (rFile);

        if (result != RES_EOF) {
            rFile = new RegistroAuxiliar();

            while (true) {
                result = file->read(rFile);
                resFile->write(*rFile);
                delete (rFile);

                if (result == RES_EOF)
                    break;

                rFile = new RegistroAuxiliar();
            }
        }
    }

    resFile->flush();
    file->destroy();
    delete (file);

    resFile->rename("IndiceInvertido");
    return resFile;
}

FileHandler::~FileHandler() {}
